
package view;

import controllers.*;
import entities.AmountRange;
import java.io.File;
import java.util.*;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import vo.ReportVO;
import ws.frachise.FranchiseVO;
import ws.login.NormalizedListEstablishment;

/**
 * @version 1.0
 * @date 13/04/2012
 * @author john
 */
public class StatsPane extends GridPane{
    
    private final static int[][] amountRanges={{-1,-1},{0,50000},{50000,100000},{100000,250000},{250000,500000},{500000,1000000},{1000000,5000000},{5000000,-1}};
    
    private final double minTypeCBoxWidth=200;
    private final double minTFWidth=200;
    private final double minCBWidth=200;
    private final double vgap=20;
    private final String initDateText="aaaa/mm/dd";
    private final String selectorHBoxClass="selector-hbox";
    private final String selectorVBoxClass="selector-vbox";
    private final String reportType="Reportes";
    private final String statsType="Estadísticas";
    
    private ObservableList<String> typesList;
    private ObservableList reportTypesList;
    private ObservableList franchisesList;
    private ObservableList establishmentsList;
    private ObservableList<AmountRange> amountRangesList;
    private ArrayList<String> establishmentsIdsList = new ArrayList<String>();
    private ArrayList<String> franchisesIdsList = new ArrayList<String>();
    
    private ServiceControl serviceControl = new ServiceControl();
    private CreateReport createReportControl = new CreateReport();
    
    //<editor-fold defaultstate="collapsed" desc="Scene Nodes">
    private HBox reportTypeHBox;
    private HBox typeHBox;
    private HBox statsMessageHBox;
    private HBox statsTopicHBox;
    private HBox groupByTimeHBox;
    private HBox groupByTransHBox;
    private HBox statsHBox;
    private VBox statsDateVBox;
    private VBox statsTopicVBox;
    private VBox groupByVBox;
    private VBox statsVBox;
    private GridPane reportsGridPane;
    private GridPane statsGridPane;
    private GridPane filterParamGrid;
    private GridPane statsParamGrid;
    private Label reportTypeL;
    private Label startDateL;
    private Label endDateL;
    private Label franchiseL;
    private Label stablishmentL;
    private Label amountRangeL;
    private Label statsTopicL;
    private Label groupByL;
    private Label showStatsL;
    private Label statsMessageL;
    private TextField startDateTF;
    private TextField endDateTF;
    private TextField dateStatsTF;
    private TextField endDateStatsTF;
    private ChoiceBox reportTypeCB;
    private ChoiceBox franchiseCB;
    private ChoiceBox stablishmentCB;
    private ChoiceBox amountRangeCB;
    private ChoiceBox typeCB;
    private Button seeReportB;
    private Button seeStatsB;
    private ToggleGroup groupByTG;
    private RadioButton groupByDayRB;
    private RadioButton groupByMonthRB;
    private RadioButton groupByYearRB;
    private CheckBox transactionNumberCheckB;
    private CheckBox amountsCheckB;
    private CheckBox groupByValidTransCheckB;
    private CheckBox groupByInvalidTransCheckB;
    private CheckBox showAverageCheckB;
    private CheckBox showMaxCheckB;
    private CheckBox showMinCheckB;
    private CheckBox showStdDeviationCheckB;
    private Tooltip startDateT;
    private Tooltip endDateT;
    private Label dateStatsL;
    private Tooltip showStatsDateT;
    private Tooltip fileSelectedT;
    private Tooltip statsTopicT;
    private Tooltip showStatsChecksT;
    //</editor-fold>

    public StatsPane(final Stage primaryStage) {
        setId("stats-pane");
        setAlignment(Pos.CENTER);
        setPadding(new Insets(30, 30, 30, 30));
        initReportsGridPane(primaryStage);
        initStatsGridPane(primaryStage);
        initTypeChoiceBox();
        initTooltips();
        add(typeHBox,0,0);
        add(reportsGridPane,0,1);
    }
    
    /**
     * Inicializa el panel que contiene los nodos necesarios para la creacion
     * de reportes.
     * @param primaryStage 
     */
    private void initReportsGridPane(final Stage primaryStage){
        reportTypesList=FXCollections.observableArrayList();
        franchisesList=FXCollections.observableArrayList();
        establishmentsList=FXCollections.observableArrayList();
        amountRangesList=FXCollections.observableArrayList();
        initReportTypeHBox();
        initFilterParamGrid();
        seeReportB=new Button("Ver reporte");
        seeReportB.setOnAction(createReport(primaryStage,this));
        GridPane.setHalignment(seeReportB, HPos.RIGHT);
        reportsGridPane=new GridPane();
        reportsGridPane.setVgap(vgap);
        reportsGridPane.add(reportTypeHBox,0,0);
        reportsGridPane.add(filterParamGrid,0,1);
        reportsGridPane.add(seeReportB,0,2);
    }
    
    /**
     * Inicializa el panel que contiene los nodos necesarios para la creacion
     * de estadisticas.
     * @param primaryStage 
     */
    private void initStatsGridPane(final Stage primaryStage){
        statsMessageL=new Label("Ver estadísticas de:");
        statsMessageHBox=new HBox(40);
        statsMessageHBox.setPadding(new Insets(20, 0, 0, 0));
        statsMessageHBox.getChildren().setAll(statsMessageL);
        seeStatsB=new Button("Ver estadísticas");
        seeStatsB.setOnAction(createStats(primaryStage,this));
        GridPane.setHalignment(seeStatsB, HPos.RIGHT);
        initStatsParamGrid();
        statsGridPane=new GridPane();
        statsGridPane.setVgap(vgap);
        statsGridPane.add(statsMessageHBox,0,0);
        statsGridPane.add(statsParamGrid,0,1);
        statsGridPane.add(seeStatsB,0,2);
    }
    
    /**
     * Inicializa los tooltips de ayuda para el usuario.
     */
    private void initTooltips(){
        startDateT=TooltipBuilder.create()
            .text("Fecha inválida")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        endDateT=TooltipBuilder.create()
            .text("Fecha inválida")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        fileSelectedT=TooltipBuilder.create()
            .text("¡Debe seleccionar un archivo!")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        statsTopicT=TooltipBuilder.create()
            .text("¡Debe seleccionar al menos un tipo de estadística!")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        showStatsChecksT=TooltipBuilder.create()
            .text("¡Debe seleccionar un estadístico por lo menos!")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        showStatsDateT=TooltipBuilder.create()
            .text("¡Ingrese una fecha!")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
    }
    
    /**
     * Recupera y muestra los posibles reportes que se pueden crear.
     */
    private void fillReportTypesList(){
        List<String> list = serviceControl.getReportTypes();
        reportTypesList.setAll(list);
//        reportTypesList.add("x");
//        reportTypesList.add("y");
    }
    
    /**
     * Inicializa los posibles rangos de dinero para la creacion de reportes.
     */
    private void fillAmountRangesList(){
        amountRangesList.clear();
        for (int[] range : amountRanges) 
            amountRangesList.add(new AmountRange(range[0], range[1]));
    }
    
    /**
     * Recupera y muestra las franquicias para la creacion de reportes.
     */
    private void fillFranchisesList(){
        FranchiseServiceControl control = new FranchiseServiceControl();
        List<FranchiseVO> list = control.listFranchise();
        franchisesList.add("Todas");
        franchisesIdsList.add("0");
        for (FranchiseVO franchiseVO : list) {
            franchisesIdsList.add(franchiseVO.getId());
            franchisesList.add(franchiseVO.getName());
        }
    }
    
    /**
     * Recupera y muestra las sucursales de la cadena de tiendas a la cual 
     * pertenece el cliente.
     */
    private void fillBranchOfficesList(){
        LoginServiceControl loginControl = new LoginServiceControl();
        establishmentsList.add("Todas");
        establishmentsList.add(new Separator());
        establishmentsIdsList.add("0");
        for (Iterator<NormalizedListEstablishment> it = loginControl.listBrand(MainWindow.getActiveUser().getBrandName()).iterator(); it.hasNext();) {
            NormalizedListEstablishment e = (NormalizedListEstablishment) it.next();
            establishmentsList.add(e.getBrandName());
            establishmentsIdsList.add(e.getBrandId());
        }
    }
    
    /**
     * Inicializa el control para la seleccion de reportes o de estaditicas.
     */
    private void initTypeChoiceBox(){
        typesList=FXCollections.observableArrayList(reportType,statsType);
        typeCB=new ChoiceBox(typesList);
        typeCB.setPrefWidth(minTypeCBoxWidth);
        typeCB.getSelectionModel().select(0);
        typeCB.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue ov, Object oldType, Object newType) {
                if(newType.toString().equals(reportType) && oldType.toString().equals(statsType)){
                    getChildren().remove(statsGridPane);
                    add(reportsGridPane,0,1);
                }else if(newType.toString().equals(statsType) && oldType.toString().equals(reportType)){
                    getChildren().remove(reportsGridPane);
                    add(statsGridPane,0,1);
                }
            }
        });
        typeHBox=new HBox();
        typeHBox.setId("type-hbox");
        typeHBox.getChildren().add(typeCB);
        typeHBox.setPrefWidth(getPrefWidth());
        typeHBox.setAlignment(Pos.CENTER_RIGHT);
        GridPane.setHalignment(typeHBox, HPos.RIGHT);
    }
    
    /**
     * Inicializa el panel superior para la eleccion del tipo de reportes.
     */
    private void initReportTypeHBox(){
        reportTypeHBox=new HBox(40);
        reportTypeHBox.setPadding(new Insets(20, 0, 0, 0));
        reportTypeL=new Label("Ver reporte de:");
        fillReportTypesList();
        reportTypeCB=new ChoiceBox<String>(reportTypesList);
        reportTypeCB.getSelectionModel().select(reportTypesList.get(0));
        reportTypeHBox.getChildren().setAll(reportTypeL,reportTypeCB);
    }
    
    /**
     * Inicializa y agrega al panel cada uno de los nodos que hacen parte del 
     * conjunto de criterios para la creacion de reportes.
     */
    private void initFilterParamGrid(){
        fillFranchisesList();
        fillBranchOfficesList();
        fillAmountRangesList();
        filterParamGrid=new GridPane();
        filterParamGrid.setPadding(new Insets(30));
        filterParamGrid.setHgap(25);
        filterParamGrid.setVgap(10);
        filterParamGrid.setId("filters-pane");
        startDateL=new Label("Fecha inicial:");
        endDateL=new Label("Fecha final:");
        franchiseL=new Label("Franquicia:");
        stablishmentL=new Label("Sucursal:");
        amountRangeL=new Label("Monto:");
        startDateTF=new TextField();
        startDateTF.setPromptText(initDateText);
        endDateTF=new TextField();
        endDateTF.setPromptText(initDateText);
        amountRangeCB=new ChoiceBox(amountRangesList);
        amountRangeCB.getSelectionModel().select(amountRangesList.get(0));
        franchiseCB=new ChoiceBox(franchisesList);
        franchiseCB.getSelectionModel().select(franchisesList.get(0));
        stablishmentCB=new ChoiceBox(establishmentsList);
        stablishmentCB.getSelectionModel().select(establishmentsList.get(0));
        startDateTF.setMinWidth(minTFWidth);
        endDateTF.setMinWidth(minTFWidth);
        amountRangeCB.setMinWidth(minCBWidth);
        franchiseCB.setMinWidth(minCBWidth);
        stablishmentCB.setMinWidth(minCBWidth);
        filterParamGrid.add(startDateL,0,0);
        filterParamGrid.add(endDateL,0,1);
        filterParamGrid.add(stablishmentL,0,2);
        filterParamGrid.add(startDateTF,1,0);
        filterParamGrid.add(endDateTF,1,1);
        filterParamGrid.add(stablishmentCB,1,2);
        filterParamGrid.add(franchiseL,2,0);
        filterParamGrid.add(amountRangeL,2,2);
        filterParamGrid.add(franchiseCB,3,0);
        filterParamGrid.add(amountRangeCB,3,2);
    }
    
    /**
     * Inicializa y agrega al panel cada uno de los nodos que hacen parte del 
     * conjunto de criterios para la creacion de estadisticas.
     */
    private void initStatsParamGrid(){
        dateStatsL=new Label("Fecha:");
        dateStatsTF=new TextField();
        dateStatsTF.setPromptText(initDateText);
        dateStatsTF.setMinWidth(minTFWidth);
        statsParamGrid=new GridPane();
        statsParamGrid.setPadding(new Insets(30));
        statsParamGrid.setVgap(10);
        statsParamGrid.setId("stats-selection-pane");
        statsTopicL=new Label("Mostrar estadísticas de:");
        groupByL=new Label("Agrupar por:");
        showStatsL=new Label("Mostrar:");
        groupByTG=new ToggleGroup();
        groupByDayRB=new RadioButton("Día");
        groupByDayRB.setToggleGroup(groupByTG);
        groupByDayRB.setSelected(true);
        groupByMonthRB=new RadioButton("Mes");
        groupByMonthRB.setToggleGroup(groupByTG);
        groupByYearRB=new RadioButton("Año");
        groupByYearRB.setToggleGroup(groupByTG);
        transactionNumberCheckB=new CheckBox("Número de transacciones");
        amountsCheckB=new CheckBox("Montos");
        groupByValidTransCheckB=new CheckBox("Transacciones válidas");
        groupByInvalidTransCheckB=new CheckBox("Transacciones inválidas");
        showAverageCheckB=new CheckBox("Promedio");
        showMaxCheckB=new CheckBox("Máximo");
        showMinCheckB=new CheckBox("Mínimo");
        showStdDeviationCheckB=new CheckBox("Desviacón estandar");
        statsTopicHBox=initHBox();
        groupByTimeHBox=initHBox();
        groupByTransHBox=initHBox();
        statsHBox=initHBox();
        statsTopicHBox.getChildren().setAll(transactionNumberCheckB,amountsCheckB);
        groupByTimeHBox.getChildren().setAll(groupByDayRB,groupByMonthRB,groupByYearRB);
        groupByTransHBox.getChildren().setAll(groupByValidTransCheckB,groupByInvalidTransCheckB);
        statsHBox.getChildren().setAll(showAverageCheckB,showMaxCheckB,showMinCheckB,showStdDeviationCheckB);
        statsTopicVBox=initVBox();
        groupByVBox=initVBox();
        statsVBox=initVBox();
        statsDateVBox=initVBox();
        statsTopicVBox.getChildren().setAll(statsTopicL,statsTopicHBox);
        groupByVBox.getChildren().setAll(groupByL,groupByTimeHBox,groupByTransHBox);
        statsVBox.getChildren().setAll(showStatsL,statsHBox);
        statsDateVBox.getChildren().setAll(dateStatsL,dateStatsTF);
        statsParamGrid.add(statsDateVBox, 0, 0);
        statsParamGrid.add(statsTopicVBox, 0, 1);
        statsParamGrid.add(groupByVBox, 0, 2);
        statsParamGrid.add(statsVBox, 0, 3);
    }
    
    /**
     * Inizializa un HBox con clase selectorHBoxClass
     * @return HBox con clase selectorHBoxClass
     */
    private HBox initHBox(){
        HBox hbox=new HBox();
        hbox.getStyleClass().add(selectorHBoxClass);
        return hbox;
    }
    
    /**
     * Inizializa un VBox con clase selectorVBoxClass
     * @return VBox con clase selectorVBoxClass
     */
    private VBox initVBox(){
        VBox vbox=new VBox();
        vbox.getStyleClass().add(selectorVBoxClass);
        return vbox;
    }
    
    /**
     * Crea un reporte con los criterios especificados por el usuario.
     * @param primaryStage
     * @param reportsStatsPane
     * @return EventHandler<ActionEvent> para la creacion de reportes
     */
    private EventHandler<ActionEvent> createReport(final Stage primaryStage,final GridPane reportsStatsPane){
        return new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                boolean validInfo=true;
                boolean checkStartDate=true;
                boolean checkEndDate=true;
                if (startDateTF.getText().toString().trim().equals(""))
                    checkStartDate=false;
                if (endDateTF.getText().toString().trim().equals(""))
                    checkEndDate=false;
                final AmountRange amountRange = (AmountRange)(amountRangeCB.getSelectionModel().getSelectedItem());
                double initialAmountValue = amountRange.getMin();
                double finalAmountValue = amountRange.getMax();
                String startDateValue = "0001/01/01";
                Calendar today=Calendar.getInstance();
                int month=(today.get(Calendar.MONTH)+1);
                int day=today.get(Calendar.DAY_OF_MONTH);
                String monthS=month<10?"0"+month:month+"";
                String dayS=day<10?"0"+day:day+"";
                String endDateValue=today.get(Calendar.YEAR)+"/"+monthS+"/"+dayS;
                if(checkStartDate){
                    if (!FormReportValidator.syntacticValidationDate(startDateTF.getText())){
                        startDateT.show(startDateL,
                            primaryStage.getX()+
                            startDateL.getLayoutX()+
                            20+
                            (primaryStage.getWidth()-filterParamGrid.getWidth())/2,
                            primaryStage.getY()+
                            startDateL.getLayoutY()+
                            filterParamGrid.getLayoutY()+
                            filterParamGrid.getPadding().getBottom()+
                            filterParamGrid.getPadding().getTop());
                        validInfo=false;
                    }else{
                        startDateValue = startDateTF.getText();
                    }
                }
                if(checkEndDate){
                    if (!FormReportValidator.syntacticValidationDate(endDateTF.getText())){
                        endDateT.show(endDateL,
                            primaryStage.getX()+
                            endDateL.getLayoutX()+
                            20+
                            (primaryStage.getWidth()-filterParamGrid.getWidth())/2,
                            primaryStage.getY()+
                            endDateL.getLayoutY()+
                            filterParamGrid.getLayoutY()+
                            filterParamGrid.getPadding().getBottom()+
                            filterParamGrid.getPadding().getTop());
                        validInfo=false;
                    }else{
                        endDateValue = endDateTF.getText();
                    }
                }
                if(validInfo){
                    FileChooser fileSelector = new FileChooser();
                    File fileToSave = fileSelector.showSaveDialog(primaryStage);
                    if (fileToSave == null){
                        fileSelectedT.show(seeReportB,
                            primaryStage.getX()+
                            seeReportB.getLayoutX()-
                            170,
                            primaryStage.getY()+
                            seeReportB.getLayoutY()+
                            getVgap()*2);
                    }else {
                        final String startDateValueF=startDateValue;
                        final String endDateValueF=endDateValue;
                        final File fileToSaveF=fileToSave;
                        final double initialAmountValueF=initialAmountValue;
                        final double finalAmountValueF=finalAmountValue;
                        Task createReportTask=new Task() {
                            @Override
                            protected Object call() throws Exception {
                                boolean result = createReportControl.createReport(fileToSaveF, serviceControl.getTransactions(startDateValueF, 
                                endDateValueF, establishmentsIdsList.get(stablishmentCB.getSelectionModel().getSelectedIndex()), 
                                MainWindow.getActiveUser().getBrandId(), franchisesIdsList.get(franchiseCB.getSelectionModel().getSelectedIndex()), 
                                reportTypeCB.getSelectionModel().getSelectedItem().toString(), initialAmountValueF, finalAmountValueF), MainWindow.getActiveUser(),
                                reportTypeCB.getSelectionModel().getSelectedItem().toString());
                                if (result){
                                    String issueDate=java.util.Calendar.getInstance().getTime().toString();
                                    String location=fileToSaveF.getAbsolutePath();
                                    String type=reportTypeCB.getSelectionModel().getSelectedItem().toString();
                                    String franchise=franchiseCB.getSelectionModel().getSelectedItem().toString();
                                    String branch=stablishmentCB.getSelectionModel().getSelectedItem().toString();
                                    String amount=amountRange.toString();
                                    ReportVO reportVO=new ReportVO(issueDate, location, type, franchise, branch, startDateValueF, endDateValueF, amount);
                                    boolean saveReportResult = ReportHistoryController.saveReport(reportVO);
                                    if(!saveReportResult)
                                        System.err.println("No se pudo guardar la entrada del reporte en el historial");
                                    updateMessage("Reporte terminado");
                                }
                                else
                                    updateMessage("Error");
                                return true;
                            }
                        };
                        createReportTask.messageProperty().addListener(new ChangeListener<String>() {
                            @Override
                            public void changed(ObservableValue<? extends String> ov, String oldMessage, String newMessage) {
                                if(!newMessage.equals("Error"))
                                    new ReportResultDialog(reportsStatsPane, primaryStage, "Reporte terminado", "El reporte se ha guardado en "+fileToSaveF.getAbsolutePath(), true).show();
                                else
                                    new ReportResultDialog(reportsStatsPane, primaryStage, "Error", "Ocurrió un error en la creación del reporte.", false).show();
                            }
                        });
                        new Thread(createReportTask).start();
                        new ReportResultDialog(reportsStatsPane, primaryStage, "Confirmación", "Reporte en construcción.", false).show();
                    }
                }
            }
        };
    }
    
    /**
     * Crea un EventHandler encargado de construir un conjunto de estadisticas 
     * con los criterios especificados por el usuario.
     * @return EventHandler<ActionEvent> para la creacion de estadisticas
     */
    private EventHandler<ActionEvent> createStats(final Stage primaryStage,final GridPane reportsStatsPane){
        return new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                boolean buildStats=true;
                if(dateStatsTF.getText().trim().equals("")){
                    showStatsDateT.setText("¡Ingrese una fecha!");
                    showStatsDateT.show(dateStatsL,
                        primaryStage.getX()+
                        dateStatsL.getLayoutX()+
                        (primaryStage.getWidth()-statsParamGrid.getWidth())/2+
                        250,
                        primaryStage.getY()+
                        statsParamGrid.getLayoutY()+
                        dateStatsL.getLayoutY()+
                        130);
                    buildStats=false;
                }
                if (buildStats) {
                    buildStats=FormReportValidator.syntacticValidationDate(dateStatsTF.getText().trim());
                    if (!buildStats) {
                        showStatsDateT.setText("¡Formato de fecha incorrecto!");
                        showStatsDateT.show(dateStatsL,
                            primaryStage.getX()
                            + dateStatsL.getLayoutX()
                            + (primaryStage.getWidth() - statsParamGrid.getWidth()) / 2
                            + 250,
                            primaryStage.getY()
                            + statsParamGrid.getLayoutY()
                            + dateStatsL.getLayoutY()
                            + 130);
                    }
                }
                if(!transactionNumberCheckB.isSelected() && !amountsCheckB.isSelected()){
                    statsTopicT.show(statsTopicL,
                        primaryStage.getX()+
                        statsTopicL.getLayoutX()+
                        (primaryStage.getWidth()-statsParamGrid.getWidth())/2+
                        250,
                        primaryStage.getY()+
                        statsParamGrid.getLayoutY()+
                        statsTopicL.getLayoutY()+
                        215);
                    buildStats=false;
                }
                if(!showAverageCheckB.isSelected() && !showMaxCheckB.isSelected() && !showMinCheckB.isSelected() && !showStdDeviationCheckB.isSelected()){
                    showStatsChecksT.show(showStatsL,
                        primaryStage.getX()+
                        showStatsL.getLayoutX()+
                        (primaryStage.getWidth()-statsParamGrid.getWidth())/2+
                        250,
                        primaryStage.getY()+
                        statsParamGrid.getLayoutY()+
                        showStatsL.getLayoutY()+
                        433);
                    buildStats=false;
                }
                if(buildStats){
                    FileChooser fileSelector = new FileChooser();
                    final File fileToSave = fileSelector.showSaveDialog(primaryStage);
                    if (fileToSave == null){
                        fileSelectedT.show(seeReportB,
                            primaryStage.getX()+
                            seeReportB.getLayoutX()-
                            170,
                            primaryStage.getY()+
                            seeReportB.getLayoutY()+
                            getVgap()*2);
                        return;
                    }
                    Task createStatsTask=new Task() {
                        @Override
                        protected Object call() throws Exception {
                            int year = Integer.parseInt(dateStatsTF.getText().trim().substring(0, 4));
                            int month = Integer.parseInt(dateStatsTF.getText().trim().substring(5, 7));
                            int day = Integer.parseInt(dateStatsTF.getText().trim().substring(8));
                            Date centralDate = new Date(year - 1900, month - 1, day);
                            boolean result = createReportControl.createStats(fileToSave, serviceControl.getTransactions("0001/01/01", 
                                    "3014/01/01", "0", MainWindow.getActiveUser().getBrandId(), "0","Todas las transacciones",-1.0,Double.MAX_VALUE),
                                    MainWindow.getActiveUser(), centralDate, transactionNumberCheckB.isSelected(), amountsCheckB.isSelected(), 
                                    groupByValidTransCheckB.isSelected(), groupByInvalidTransCheckB.isSelected(), 
                                    groupByDayRB.isSelected()?'d':groupByMonthRB.isSelected()?'m':'y');
                            if (result)
                                updateMessage("Estadisticas terminadas");
                            else
                                updateMessage("Error");
                            return true;
                        }
                    };
                    createStatsTask.messageProperty().addListener(new ChangeListener<String>() {
                        @Override
                        public void changed(ObservableValue<? extends String> ov, String oldMessage, String newMessage) {
                            if(!newMessage.equals("Error"))
                                new ReportResultDialog(reportsStatsPane, primaryStage, "Estadísticas terminadas", "El reporte de estadísticas se ha guardado en "+fileToSave.getAbsolutePath(), true).show();
                            else
                                new ReportResultDialog(reportsStatsPane, primaryStage, "Error", "Ocurrió un error en la creación del reporte.", false).show();
                        }
                    });
                    new Thread(createStatsTask).start();
                    new ReportResultDialog(reportsStatsPane, primaryStage, "Confirmación", "Reporte de estadísticas en construcción.", false).show();
                }
            }
        };
    }
    
    /**
     * Deja en su estado inicial todos los controles para la creacion de 
     * reportes y estadisticas.
     */
    protected void cleanFields(){
        startDateTF.setText("");
        endDateTF.setText("");
        reportTypeCB.getSelectionModel().select(0);
        franchiseCB.getSelectionModel().select(0);
        stablishmentCB.getSelectionModel().select(0);
        amountRangeCB.getSelectionModel().select(0);
    }
    
}
